.NET 向Amazon S3批量上传数据

.NET 从TELERIK批量获取数据

我在上传数据时使用PutObjectRequest类,其中的Key属性有严格限制,稍有不慎就会进坑,而创建一个假文件(48B或48K左右)

 

put.Key=文件夹名+"/"+ 文件名

文件名=本地文件名`</pre>
</div>
思路:遍历文件夹,读取所有文件夹、文件夹内文件,使用Task循环上传

&nbsp;
<div>
<pre>`class UploadFilesInAll
{
    /// &lt;summary&gt;
    /// 访问密钥
    /// &lt;/summary&gt;
    private static String accessKeyID = "访问密钥id";
    /// &lt;summary&gt;
    /// 密钥
    /// &lt;/summary&gt;
    private static String secretKey = "私有访问密钥iD";
    /// &lt;summary&gt;
    /// 存储桶的名字
    /// &lt;/summary&gt;
    private static String bucketName = "存储桶名字";
    /// &lt;summary&gt;
    /// 存放上传失败的文件的信息
    /// &lt;/summary&gt;
    private static List&lt;string&gt; errorList = new List&lt;string&gt;();
    /// &lt;summary&gt;
    /// 存放获取到的路径
    /// &lt;/summary&gt;
    static List&lt;string&gt; fileList = new List&lt;string&gt;();
    /// &lt;summary&gt;
    /// 成功个数
    /// &lt;/summary&gt;
    static int successMum = 0;
    /// &lt;summary&gt;
    /// 失败个数
    /// &lt;/summary&gt;
    static int failedNum = 0;
    /// &lt;summary&gt;
    /// file个数
    /// &lt;/summary&gt;
    static int fileCount = 0;
    /// &lt;summary&gt;
    /// folder个数
    /// &lt;/summary&gt;
    static int folderCount = 0;

    /// &lt;summary&gt;
    /// 批量上传文件的主体部分
    /// &lt;/summary&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public static string UploadAllFiles()
    {
        #region 删除日志文件
        string filePath = AppDomain.CurrentDomain.BaseDirectory + "Log.txt";
        if (System.IO.File.Exists(filePath))
        {
            System.IO.File.Delete(filePath);
        } 
        #endregion

        string localPath = "";
        AWSCredentials credentials;
        credentials = new BasicAWSCredentials(accessKeyID.Trim(), secretKey.Trim());
        AmazonS3Client s3Client = new AmazonS3Client(accessKeyID.Trim(), secretKey.Trim(), Amazon.RegionEndpoint.USEast1);
        Console.WriteLine("验证成功");
        Console.WriteLine("检查存储桶是否存在");
        if (!Program.CheckBucketExists(s3Client, bucketName))
        {
            Console.WriteLine("正在创建数据桶........");
            s3Client.PutBucket(bucketName);
            Console.WriteLine("数据桶创建成功");
        }

        Dictionary&lt;string, List&lt;string&gt;&gt; fileList = UploadFilesInAll.GetAllFiles(@"E:\telerikFile");
        WriteLog("共有" + fileCount + "个文件");
        // 整理文件的路径,逐个上传
        foreach (var item in fileList)
        {
            string key = item.Key.Substring(item.Key.LastIndexOf('\\'));
            key = key.Substring(key.LastIndexOf('\\') + 1);
            Console.WriteLine(key);
            foreach (var item_ in item.Value)
            {
                localPath = item_;
                string path = item_.Substring(item_.LastIndexOf('\\')+1);
                Task.Run(()=&gt; UploadFilesInAll.upload(s3Client, key+"/"+ path, item_));
            }
        }
        try
        {
            Console.WriteLine("准备上传");
            return "success";
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());

            return "failed";
        }

    }

    /// &lt;summary&gt;
    /// 文件上传部分
    /// &lt;/summary&gt;
    /// &lt;param name="s3Client"&gt;Amazon S3服务接口&lt;/param&gt;
    /// &lt;param name="key"&gt;对象键(文件上传后存储的文件夹/文件)&lt;/param&gt;
    /// &lt;param name="localFile"&gt;待上传数据存放路径&lt;/param&gt;
    private static void upload(AmazonS3Client s3Client,string key,string localFile)
    {
        Object objLock = new Object();
        lock(objLock)
        {
            try
            {
                // 配置上传信息
                string localPath = localFile;
                PutObjectRequest obj = new PutObjectRequest();
                var fileStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
                obj.InputStream = fileStream;
                obj.BucketName = bucketName;
                obj.Key = key;
                obj.CannedACL = S3CannedACL.PublicRead;
                Console.WriteLine("正在上传" + localPath);
                // 默认添加public权限  
                s3Client.PutObject(obj);
                Console.WriteLine("上传成功第"+ (successMum+1) +"个文件" );
                WriteLog("上传成功第" + (successMum+1) + "个文件" + localPath);
                successMum++;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Console.WriteLine("上传失败"+ (failedNum+1) + "个文件" + localFile);
                errorList.Add(localFile);
                //WriteLog(" 失败" + filedNum++ + "个");
                failedNum++;
                WriteLog("上传失败" + localFile);
                // return "failed";
            }
        }
        if(successMum + 1== fileCount)
        {
            Console.WriteLine("文件已经全部下载,按任意键退出");
            WriteLog("文件已经全部下载");
            Console.ReadKey();
        }

        if(failedNum &gt;=1)
        {
            WriteLog("当前失败率=" + failedNum * 1.00 / fileCount);
            ShowError(s3Client);
        }
        else
        {
            //WriteLog("当前失败率=" + failedNum * 1.00 / fileCount);
        }

    }

    /// &lt;summary&gt;
    /// 再次上传主体部分
    /// &lt;/summary&gt;
    /// &lt;param name="s3Client"&gt;Amazon S3服务主体部分&lt;/param&gt;
    /// &lt;param name="failedPath"&gt;&lt;/param&gt;
    private static void uploadAgain(AmazonS3Client s3Client,string failedPath)
    {

        Object objLock = new Object();
        lock (objLock)
        {
            try
            {
                string key = failedPath.Substring(failedPath.LastIndexOf('\\'));
                key = key.Substring(key.LastIndexOf('\\') + 1);

                string localPath = failedPath;
                PutObjectRequest obj = new PutObjectRequest();
                var fileStream = new FileStream(localPath, FileMode.Open, FileAccess.Read);
                obj.InputStream = fileStream;
                obj.BucketName = bucketName;
                obj.Key = key;
                obj.CannedACL = S3CannedACL.PublicRead;
                Console.WriteLine("正在上传" + localPath);
                // 默认添加public权限  
                s3Client.PutObject(obj);
                Console.WriteLine("上传成功" + localPath);
                successMum++;
                errorList.Remove(localPath);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
                Console.WriteLine("上传失败" + failedPath);
                errorList.Add(failedPath);
                failedNum++;
                WriteLog(failedPath);
            }
            if ((failedNum * 1.00 / fileCount) &gt; 0.00)
            {
                WriteLog("成功下载" + successMum + "个文件,失败" + failedNum + "个文件");
                ShowError(s3Client);
            }
        }
    }

    /// &lt;summary&gt;
    /// 整理错误信息,准备重新下载之前下载失败的文件
    /// &lt;/summary&gt;
    /// &lt;param name="s3Client"&gt;AmazonS3服务实例&lt;/param&gt;
    private static void ShowError(AmazonS3Client s3Client)
    {
        Object objLock = new Object();
        lock (objLock)
        {
            int i = 0;
            string path = "";
            Console.WriteLine("当前失败率=" + failedNum * 1.00 / fileCount);
            WriteLog("当前失败率=" + failedNum * 1.00 / fileCount);
            try
            {
                successMum = 0;
                failedNum = 0;
                foreach (var item in errorList)
                {
                    i++;
                    path = item;
                    Console.WriteLine(item);
                    Task.Run(() =&gt; uploadAgain(s3Client, item));
                }
            }
            catch
            {
                WriteLog("第"+i+"个失败:" + path);
                Console.WriteLine("执行错误");
            }

        }
    }     

    /// &lt;summary&gt;
    /// 获取所有文件的路径
    /// &lt;/summary&gt;
    /// &lt;param name="path"&gt;&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public static Dictionary&lt;string, List&lt;string&gt;&gt; GetAllFiles(string path)
     {
        Dictionary&lt;string, List&lt;string&gt;&gt; fileTree = new Dictionary&lt;string, List&lt;string&gt;&gt;();
        List&lt;string&gt; list;
        DirectoryInfo[] folder = new DirectoryInfo(@"E:\telerikFile").GetDirectories();
        for (int i = 0; i &lt; folder.Length; i++)
        {
            folderCount++;
            list = list = new List&lt;string&gt;();
            for (int j = 0; j &lt; folder[i].GetFiles().Length; j++)
            {
                fileCount++;
                list.Add(folder[i].GetFiles()[j].FullName.ToString());
            }
            fileTree.Add(folder[i].FullName, list);

            // list.Clear();
        }
        WriteLog("共有"+ folderCount +"个文件夹,"+ fileCount+"个文件");
        return fileTree;
        //foreach (var dicName in list)
        //{
        //    Console.WriteLine(dicName);
        //    Console.WriteLine(dicName.Count());
        //}
    }

    /// &lt;summary&gt;
    /// 获取指定的根目录的所有子目录名称
    /// &lt;/summary&gt;
    /// &lt;param name="path"&gt;指定的根目录&lt;/param&gt;
    /// &lt;returns&gt;子目录名称集合&lt;/returns&gt;
    public static List&lt;string&gt; getPath(string path)
    {
        DirectoryInfo dir = new DirectoryInfo(path);
        FileInfo[] fil = dir.GetFiles();
        DirectoryInfo[] dii = dir.GetDirectories();
        foreach (FileInfo f in fil)
        {
            fileList.Add(f.FullName);//添加文件的路径到列表
        }
        //获取子文件夹内的文件列表,递归遍历
        foreach (DirectoryInfo d in dii)
        {
            getPath(d.FullName);
            fileList.Add(d.FullName);//添加文件夹的路径到列表
        }
        return fileList;
    }

    /// &lt;summary&gt;
    /// 写入文件,做记录测试
    /// &lt;/summary&gt;
    /// &lt;param name="str"&gt;&lt;/param&gt;
    private static void WriteLog(string str)
    {
        Task.Run(() =&gt;
        {
            try
            {
                string filePath = AppDomain.CurrentDomain.BaseDirectory + "Log.txt";
                StreamWriter sw = null;
                if (!System.IO.File.Exists(filePath))
                {
                    sw = System.IO.File.CreateText(filePath);
                }
                else
                {
                    sw = System.IO.File.AppendText(filePath);
                }
                sw.Write(str + Environment.NewLine);//+ DateTime.Now.ToString()
                sw.Close();
            }
            catch (Exception ex)
            {
                ex.ToString();
            }
        });
    }
}


 

文章目录
|